package graphicView;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTextField;
import javax.swing.JList;
import javax.swing.JLabel;
import javax.swing.ListSelectionModel;

import model.*;

/**
 * Team EBE
 * 
 * ClassGUI.java is the user interface to edit a class
 * 
 */
public class ClassGUI extends JPanel implements ActionListener, Observer{

	private static final long serialVersionUID = 1L;
	private JFrame classframe;
	private GraphicController controller;

	// declare the components
	JTextField classNameField = new JTextField(30);
	JTextField attributeNameField = new JTextField(30);
	JTextField attributeTypeField = new JTextField();
	JTextField attributeVisField = new JTextField();
	JList attributeList;
	JButton insertAttribute = new JButton("Insert AttributeImpl");
	JButton deleteAttribute = new JButton("Delete AttributeImpl");
	JTextField operationNameField = new JTextField();
	JTextField operationTypeField = new JTextField();
	JTextField operationVisField = new JTextField();
	JList operationList;
	JButton insertOperation = new JButton("Insert OperationImpl");
	JButton deleteOperation = new JButton("Delete OperationImpl");
	JButton updateClass = new JButton("Update ClassImpl");
	JButton cancelChanges = new JButton("Cancel");
	JScrollPane attributeListScrollPane;
	JScrollPane operationListScrollPane;
	
	String[] visibilityOptions = { "+    Public", "-     Private", "#    Protected", "~    Package", "/     Derived"}; 
	JComboBox attVisOptions = new JComboBox(visibilityOptions);
	JComboBox opVisOptions = new JComboBox(visibilityOptions);
	DefaultListModel attributeListModel;
	DefaultListModel operationListModel;

	// the class we will be editing
	ClassEditor theEditor;

	// vectors of attributes and operations of the class we will be editing
	Vector<AttributeImpl> theAttributes;
	Vector<OperationImpl> theOperations;

	int attributesAdded;
	int operationsAdded;

	public ClassGUI(GraphicController Controller, JFrame cFrame,
			ClassEditor editor) {
		classframe = cFrame;
		controller = Controller;
		theEditor = editor;

		operationListModel = new DefaultListModel();
		attributeListModel = new DefaultListModel();
		initFields();
		JPanel ClassPanel = setupClassLayout();
		classframe.getContentPane().add(ClassPanel, BoxLayout.X_AXIS);
	}

	private void initFields() {

		attributesAdded = operationsAdded = 0;
		classNameField.setText(theEditor.getName());
		theOperations = theEditor.getOperationList();
		operationListModel.clear();
		for (OperationImpl o : theOperations) {
			operationListModel.addElement(o.toString());
		}

		operationList = new JList(operationListModel);
		// Create the list and put it in a scroll pane.

		operationList.setVisibleRowCount(5);
		operationListScrollPane = new JScrollPane(operationList);

		theAttributes = theEditor.getAttributeList();
		attributeListModel.clear();
		for (AttributeImpl a : theAttributes) {
			attributeListModel.addElement(a.toString());
		}

		attributeList = new JList(attributeListModel);
		// Create the list and put it in a scroll pane.

		attributeList.setVisibleRowCount(5);
		attributeListScrollPane = new JScrollPane(attributeList);

	}

	private JPanel setupClassLayout() {

		//create the mane panel for the inspector uses box layout to stack elements vertically
		JPanel classPanel = new JPanel();
		classPanel.setLayout(new BoxLayout(classPanel, BoxLayout.Y_AXIS));

		//sets the command to issue to the listener when the buttons are pressed
		insertAttribute.setActionCommand("addAttribute");
		
		deleteAttribute.setActionCommand("deleteAttribute");

		insertOperation.setActionCommand("addOperation");
		
		deleteOperation.setActionCommand("deleteOperation");

		updateClass.setActionCommand("class");

		cancelChanges.setActionCommand("cancel");

		//creates the action listeners for the buttons
		insertAttribute.addActionListener(this);
		insertOperation.addActionListener(this);
		deleteAttribute.addActionListener(this);
		deleteOperation.addActionListener(this);
		attVisOptions.addActionListener(this);
		opVisOptions.addActionListener(this);
		
		updateClass.addActionListener(this);
		cancelChanges.addActionListener(this);

		//creates and adds the panel for class name
		JPanel classNamePanel = new JPanel();
		classNamePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));
		classNamePanel.add(new JLabel("ClassImpl name"));
		classNamePanel.add(classNameField);

		classPanel.add(classNamePanel);

		//creates the middle panel which holds the inspectors for attributes and operations
		JPanel attributesAndOperationsPanel = new JPanel();
		attributesAndOperationsPanel.setLayout(new BoxLayout(
				attributesAndOperationsPanel, BoxLayout.Y_AXIS));

		JPanel attributePanel = new JPanel();
		attributePanel.setLayout(new GridLayout(1, 2));

		//creates the attribute editor
		JPanel attributeEditPanel = new JPanel();
		attributeEditPanel.setLayout(new GridLayout(4, 2));
		attributeEditPanel.add(new JLabel("Name"));
		attributeEditPanel.add(attributeNameField);
		attributeEditPanel.add(new JLabel("Type"));
		attributeEditPanel.add(attributeTypeField);
		attributeEditPanel.add(new JLabel("Visibility"));
		attributeEditPanel.add(attVisOptions);
//		attributeEditPanel.add(attributeVisField);
		attributeEditPanel.add(insertAttribute);
		attributeEditPanel.add(deleteAttribute);

		attributePanel.add(attributeEditPanel);
		
		//creates the viewer for the list of existing attributes
		JPanel attributeListPanel = new JPanel();
		attributeListPanel.setLayout(new GridLayout(1, 1));
		attributeListPanel.add(attributeListScrollPane);
		attributePanel.add(attributeListPanel);

		attributePanel
				.setBorder(BorderFactory.createTitledBorder("Attributes"));

		attributesAndOperationsPanel.add(attributePanel);

		
		//same as attributes except for operation
		JPanel operationPanel = new JPanel();
		operationPanel.setLayout(new GridLayout(1, 2));

		JPanel operationEditPanel = new JPanel();
		operationEditPanel.setLayout(new GridLayout(4, 2));
		operationEditPanel.add(new JLabel("Name"));
		operationEditPanel.add(operationNameField);
		operationEditPanel.add(new JLabel("Type"));
		operationEditPanel.add(operationTypeField);
		operationEditPanel.add(new JLabel("Visibility"));
		operationEditPanel.add(opVisOptions);
//		operationEditPanel.add(attributeVisField);
		operationEditPanel.add(insertOperation);
		operationEditPanel.add(deleteOperation);

		operationPanel.add(operationEditPanel);

		JPanel operationListPanel = new JPanel();
		operationListPanel.setLayout(new GridLayout(1, 1));
		operationListPanel.add(operationListScrollPane);
		operationPanel.add(operationListPanel);

		operationPanel
				.setBorder(BorderFactory.createTitledBorder("Operations"));

		attributesAndOperationsPanel.add(operationPanel);

		classPanel.add(attributesAndOperationsPanel);

		//creates a panel for the update and cancle buttons
		JPanel classButtonPanel = new JPanel();
		classButtonPanel.setLayout(new GridLayout(2, 1));
		classButtonPanel.add(updateClass);
		classButtonPanel.add(cancelChanges);

		classPanel.add(classButtonPanel);

		classPanel.setPreferredSize(new Dimension(700, 385));

		return classPanel;

	}

	public void actionPerformed(ActionEvent e) {
        String attVis = (String)attVisOptions.getSelectedItem();
        String opVis = (String)opVisOptions.getSelectedItem();
        
        char attVisC = attVis.charAt(0);
        char opVisC = opVis.charAt(0);
		
		if ("addAttribute".equals(e.getActionCommand())) {
			if (!attributeNameField.getText().isEmpty()
//					&& attributeVisField.getText().length() == 1
					&& !attributeTypeField.getText().isEmpty()) {
				theAttributes.add(new AttributeImpl(attributeNameField.getText(),
						attributeTypeField.getText(), attVisC));
				attributeListModel.addElement(theAttributes.lastElement());
				++attributesAdded;
			}

		} else if("deleteAttribute".equals(e.getActionCommand())){ 
		
		
		
		
		}else if ("addOperation".equals(e.getActionCommand())) {
			if (!operationNameField.getText().isEmpty()
					&& operationVisField.getText().length() == 1
					&& !operationTypeField.getText().isEmpty()) {
				theOperations.add(new OperationImpl(operationNameField.getText(),
						operationTypeField.getText(), opVisC));
				operationListModel.addElement(theOperations.lastElement());
				++operationsAdded;
			}

		} else if("deleteOperation".equals(e.getActionCommand())){ 
		
		
		
		
		} else if ("cancel".equals(e.getActionCommand())) {
			attributeListModel.clear();
			operationListModel.clear();
			for (int i = 0; i < operationsAdded; i++) {
				theEditor.removeLastOperation();
			}
			for (int i = 0; i < attributesAdded; i++) {
				theEditor.removeLastAttribute();
			}
			initFields();

		} else if ("class".equals(e.getActionCommand())) {
			theEditor.commitEdits(classNameField.getText( ));
			operationsAdded = 0;
			attributesAdded = 0;

		}
		
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		initFields();
		
	}

}